const multer = require('multer');
const path = require('path');
const fs = require('fs').promises;
const Jimp = require('jimp');
const { asyncHandler } = require('../middleware/errorHandler');
const { success, error } = require('../utils/common');
const logger = require('../utils/logger');

// 配置文件存储
const storage = multer.diskStorage({
  destination: async (req, file, cb) => {
    const uploadDir = path.join(__dirname, '../../public/upload', file.fieldname);
    try {
      await fs.mkdir(uploadDir, { recursive: true });
      cb(null, uploadDir);
    } catch (err) {
      cb(err);
    }
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    const ext = path.extname(file.originalname);
    cb(null, file.fieldname + '-' + uniqueSuffix + ext);
  }
});

// 文件过滤器
const fileFilter = (req, file, cb) => {
  const allowedTypes = {
    'image': ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
    'video': ['video/mp4', 'video/avi', 'video/mov', 'video/wmv'],
    'audio': ['audio/mp3', 'audio/wav', 'audio/ogg', 'audio/m4a'],
    'document': ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document']
  };

  const fileType = req.body.type || 'image';
  if (allowedTypes[fileType] && allowedTypes[fileType].includes(file.mimetype)) {
    cb(null, true);
  } else {
    cb(new Error('不支持的文件类型'), false);
  }
};

// 创建multer实例
const upload = multer({
  storage,
  fileFilter,
  limits: {
    fileSize: 50 * 1024 * 1024 // 50MB
  }
});

class UploadController {
  /**
   * 上传图片
   */
  static uploadImage = [
    upload.single('image'),
    asyncHandler(async (req, res) => {
      if (!req.file) {
        return res.status(400).json(error('请选择要上传的图片'));
      }

      const file = req.file;
      const filePath = file.path;
      const fileName = file.filename;

      try {
        // 处理图片
        const image = await Jimp.read(filePath);
        
        // 生成缩略图
        const thumbnail = image.clone().resize(300, 300);
        const thumbnailPath = path.join(path.dirname(filePath), 'thumb_' + fileName);
        await thumbnail.writeAsync(thumbnailPath);

        // 生成中等尺寸图片
        const medium = image.clone().resize(800, 800);
        const mediumPath = path.join(path.dirname(filePath), 'medium_' + fileName);
        await medium.writeAsync(mediumPath);

        const fileUrl = `/upload/image/${fileName}`;
        const thumbnailUrl = `/upload/image/thumb_${fileName}`;
        const mediumUrl = `/upload/image/medium_${fileName}`;

        logger.info(`用户 ${req.user?.id || 'anonymous'} 上传图片: ${fileName}`);

        res.json(success({
          original: fileUrl,
          thumbnail: thumbnailUrl,
          medium: mediumUrl,
          filename: fileName,
          size: file.size,
          mimetype: file.mimetype
        }, '图片上传成功'));

      } catch (err) {
        // 删除上传的文件
        await fs.unlink(filePath).catch(() => {});
        throw err;
      }
    })
  ];

  /**
   * 上传视频
   */
  static uploadVideo = [
    upload.single('video'),
    asyncHandler(async (req, res) => {
      if (!req.file) {
        return res.status(400).json(error('请选择要上传的视频'));
      }

      const file = req.file;
      const fileUrl = `/upload/video/${file.filename}`;

      logger.info(`用户 ${req.user?.id || 'anonymous'} 上传视频: ${file.filename}`);

      res.json(success({
        url: fileUrl,
        filename: file.filename,
        size: file.size,
        mimetype: file.mimetype
      }, '视频上传成功'));
    })
  ];

  /**
   * 上传音频
   */
  static uploadAudio = [
    upload.single('audio'),
    asyncHandler(async (req, res) => {
      if (!req.file) {
        return res.status(400).json(error('请选择要上传的音频'));
      }

      const file = req.file;
      const fileUrl = `/upload/audio/${file.filename}`;

      logger.info(`用户 ${req.user?.id || 'anonymous'} 上传音频: ${file.filename}`);

      res.json(success({
        url: fileUrl,
        filename: file.filename,
        size: file.size,
        mimetype: file.mimetype
      }, '音频上传成功'));
    })
  ];

  /**
   * 上传文档
   */
  static uploadDocument = [
    upload.single('document'),
    asyncHandler(async (req, res) => {
      if (!req.file) {
        return res.status(400).json(error('请选择要上传的文档'));
      }

      const file = req.file;
      const fileUrl = `/upload/document/${file.filename}`;

      logger.info(`用户 ${req.user?.id || 'anonymous'} 上传文档: ${file.filename}`);

      res.json(success({
        url: fileUrl,
        filename: file.filename,
        size: file.size,
        mimetype: file.mimetype
      }, '文档上传成功'));
    })
  ];

  /**
   * 批量上传
   */
  static batchUpload = [
    upload.array('files', 10), // 最多10个文件
    asyncHandler(async (req, res) => {
      if (!req.files || req.files.length === 0) {
        return res.status(400).json(error('请选择要上传的文件'));
      }

      const files = req.files;
      const results = [];

      for (const file of files) {
        const fileUrl = `/upload/${file.fieldname}/${file.filename}`;
        
        results.push({
          url: fileUrl,
          filename: file.filename,
          size: file.size,
          mimetype: file.mimetype
        });

        logger.info(`用户 ${req.user?.id || 'anonymous'} 批量上传文件: ${file.filename}`);
      }

      res.json(success(results, '批量上传成功'));
    })
  ];

  /**
   * 删除文件
   */
  static deleteFile = asyncHandler(async (req, res) => {
    const { filename, type = 'image' } = req.params;

    if (!filename) {
      return res.status(400).json(error('文件名不能为空'));
    }

    const filePath = path.join(__dirname, '../../public/upload', type, filename);

    try {
      await fs.access(filePath);
      await fs.unlink(filePath);

      // 如果是图片，同时删除缩略图和中等尺寸图片
      if (type === 'image') {
        const thumbnailPath = path.join(path.dirname(filePath), 'thumb_' + filename);
        const mediumPath = path.join(path.dirname(filePath), 'medium_' + filename);

        await fs.unlink(thumbnailPath).catch(() => {});
        await fs.unlink(mediumPath).catch(() => {});
      }

      logger.info(`用户 ${req.user?.id || 'anonymous'} 删除文件: ${filename}`);

      res.json(success(null, '文件删除成功'));
    } catch (err) {
      if (err.code === 'ENOENT') {
        return res.status(404).json(error('文件不存在'));
      }
      throw err;
    }
  });

  /**
   * 获取文件信息
   */
  static getFileInfo = asyncHandler(async (req, res) => {
    const { filename, type = 'image' } = req.params;

    if (!filename) {
      return res.status(400).json(error('文件名不能为空'));
    }

    const filePath = path.join(__dirname, '../../public/upload', type, filename);

    try {
      const stats = await fs.stat(filePath);
      const fileUrl = `/upload/${type}/${filename}`;

      res.json(success({
        url: fileUrl,
        filename,
        size: stats.size,
        created_at: stats.birthtime,
        modified_at: stats.mtime
      }, '获取成功'));
    } catch (err) {
      if (err.code === 'ENOENT') {
        return res.status(404).json(error('文件不存在'));
      }
      throw err;
    }
  });
}

module.exports = UploadController; 